package com.todaynews.frame.asynctask;

/**
 * [description about this class]
 * 安全异步任务，可以捕获任意异常，并反馈给给开发者。
 * 从执行前，执行中，执行后，乃至更新时的异常都捕获。
 * 如果用户取消了任务，那么会将回调onCancelled()。
 * @author jack
 */

public abstract class SafeTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> {

    private Exception cause;
    private boolean printStackTrace = true;

    @Override
    protected final void onPreExecute() {
        try {
            onPreExecuteSafely();
        } catch (Exception e) {
            if (printStackTrace){
                e.printStackTrace();
            }
        }
    }

    @Override
    protected final Result doInBackground(Params... params) {
        try {
            return doInBackgroundSafely(params);
        } catch (Exception e) {
            if (printStackTrace) {
                e.printStackTrace();
            }
            cause = e;
        }
        return null;
    }

    @Override
    protected final void onProgressUpdate(Progress... values) {
        try {
            onProgressUpdateSafely(values);
        } catch (Exception e) {
            if (printStackTrace) {
                e.printStackTrace();
            }
        }
    }

    @Override
    protected final void onPostExecute(Result result) {
        try {
            onPostExecuteSafely(result, cause);
        } catch (Exception e) {
            if (printStackTrace) {
                e.printStackTrace();
            }
        }
    }

    @Override
    protected final void onCancelled(Result result) {
        onCancelled();
    }

    /**
     *  取代了{@link AsyncTask#onPreExecute()}, 这个方法的任意异常都能被捕获：它是安全的。
     *  注意：本方法将在开发者启动任务的线程执行。
     */
    protected void onPreExecuteSafely() throws Exception {}

    /**
     * Child Thread
     * 取代了doInBackground(Object...), 这个方法的任意异常都能被捕获：它是安全的。
     * 如果它发生了异常，Exception将会通过{onPostExecuteSafely(Object, Exception)}
     * 传递。
     * @param params 入参
     * @return
     */
    protected abstract Result doInBackgroundSafely(Params... params) throws Exception;

    /**
     * Main UI Thread
     * 注意：本方法一定执行在主线程, 这个方法的任意异常都能被捕获：它是安全的。
     *
     * @param result
     */
    protected void onPostExecuteSafely(Result result, Exception e) throws Exception {}

    /**
     * Main UI Thread
     * 这个方法的任意异常都能被捕获：它是安全的。
     *
     * @param values 更新传递的值
     */
    protected void onProgressUpdateSafely(Progress... values) throws Exception {}

}
